package ar.edu.unlu.sistemas.p2p.business.msg;

import org.jdom.Document;
import org.jdom.Element;

import ar.edu.unlu.sistemas.p2p.business.util.XMLManager;

public class MessageFactory {
	
	public static final int CODE_CONNECT_PEER_NODE = 100;
	public static final int CODE_CONNECT_PEER_NODE_ACK = 101;
	public static final int CODE_DISCONNECT_PEER_NODE = 102;
	public static final int CODE_DISCONNECT_PEER_NODE_ACK = 103;
	public static final int CODE_CONNECTION_ALIVE = 104;
	public static final int CODE_CONNECTION_ALIVE_ACK = 105;
	public static final int CODE_PING = 106;
	public static final int CODE_PONG = 107;
	public static final int CODE_QUERY = 108;
	public static final int CODE_QUERY_RESP = 109;
	
	/**
	 * Recibe el string con el contenido del mensaje en formato xml y lo procesa con el fin
	 * de retornar un objeto mensaje de la clase que representa al mensaje correpondiente.
	 * 
	 * @param xmlContent
	 * @return messageObject
	 */
	public static Message buildFromXML(String xmlContent) {
		Document xmlDoc = XMLManager.getInstance().buildXMLDocFromString(xmlContent);
		if (xmlDoc != null) {
			Element root = xmlDoc.getRootElement();
			Element head = root.getChild(Header.TAG_ROOT);
			int code = Integer.parseInt(head.getChildText(Header.TAG_MSG_TYPE));
			return buildFromXML(code, xmlDoc);
		} else {
			return null;
		}
			
	}
	
	/**
	 * Obtenido el código del mensaje, se lo envía por parámetro a este método para que
	 * instancie y retorne la clase correspondiente al mismo.
	 * 
	 * @param code
	 * @param xmlDoc
	 * @return messageObject
	 */
	private static Message buildFromXML(int code, Document xmlDoc) {
		switch (code) {
			case CODE_CONNECT_PEER_NODE:
				return new PeerConnectionMessage(xmlDoc);
			case CODE_CONNECT_PEER_NODE_ACK:
				return new PeerConnectionACKMessage(xmlDoc);
			case CODE_DISCONNECT_PEER_NODE:
				return new PeerDisconnectionMessage(xmlDoc);
			case CODE_DISCONNECT_PEER_NODE_ACK:
				return new PeerDisconnectionACKMessage(xmlDoc);
			case CODE_CONNECTION_ALIVE:
				return new ConnectionAliveMessage(xmlDoc);
			case CODE_CONNECTION_ALIVE_ACK:
				return new ConnectionAliveACKMessage(xmlDoc);
			case CODE_PING:
				return new PingMessage(xmlDoc);
			case CODE_PONG:
				return new PongMessage(xmlDoc);
			case CODE_QUERY:
				return new QueryMessage(xmlDoc);
			case CODE_QUERY_RESP:
				return new QueryResponseMessage(xmlDoc);
			default:
				return null;
		}
	}
	
	/**
	 * Instancia un mensaje según su código que recibe como parámetro. Se retorna al mismo.
	 * 
	 * @param code
	 * @return messageObject
	 */
	public static Message getMessage(int code) {
		switch (code) {
			case CODE_CONNECT_PEER_NODE:
				return new PeerConnectionMessage();
			case CODE_CONNECT_PEER_NODE_ACK:
				return new PeerConnectionACKMessage();
			case CODE_DISCONNECT_PEER_NODE:
				return new PeerDisconnectionMessage();
			case CODE_DISCONNECT_PEER_NODE_ACK:
				return new PeerDisconnectionACKMessage();
			case CODE_CONNECTION_ALIVE:
				return new ConnectionAliveMessage();
			case CODE_CONNECTION_ALIVE_ACK:
				return new ConnectionAliveACKMessage();
			case CODE_PING:
				return new PingMessage();
			case CODE_PONG:
				return new PongMessage();
			case CODE_QUERY:
				return new QueryMessage();
			case CODE_QUERY_RESP:
				return new QueryResponseMessage();
			default:
				return null;
		}
	}
	

}
